package cn.org.wifit.core.zookeeper.manager;

import java.util.List;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;

import cn.org.wifit.core.zookeeper.watcher.IMServerWatcher;
import cn.org.wifit.core.zookeeper.watcher.IMUserWatcher;

/**
 * private static final ZookeeperReadManager READ_MANAGER = new ZookeeperReadManager();<br>
 * 本来应该使用自主的单例模式，但是当引入了spring框架后，我们可以使用spring的配置文件，将zookeeperReadManager设置为单例模式<br>
 * <br>
 * ZookeeperReadManager将帮助每个服务器工程建立zookeeper的节点更新监听，以便最终实现对ServerNodeTree对象的更新
 * @author yinwenjie
 * @see Spring spring 3.x scope="singleton"
 */
public class ZookeeperReadManager {
	/**
	 * 由spring托管的一个单例对象
	 */
	private ZooKeeper zk;
	
	/**
	 * 这个watcher专门用于监控IMUser节点以及其子节点的变化
	 */
	private IMUserWatcher imUserWatcher;
	
	/**
	 * 这个watcher专门用于监控IMServer节点以及子节点的变化
	 */
	private IMServerWatcher imServerWatcher;
	
	/**
	 * 由spring参数化zookeeper.properties文件后传来的zookeeper服务集群连接信息
	 * @param zookeeper_path
	 */
	public ZookeeperReadManager(ZooKeeper zk  , IMUserWatcher imUserWatcher , IMServerWatcher imServerWatcher) {
		this.zk = zk;
		this.imServerWatcher = imServerWatcher;
		this.imUserWatcher = imUserWatcher;
		
		/*
		 * 注意，由于有spring的接入，所以这里传入的this.zk已经建立连接。
		 * 以下我们将检查zookeeper服务集群上是否有了我们所需要的各节点，包括：
		 * /IMServer
		 * /IMUser
		 * /IMUser/ipxs
		 * /IMUser/IDSections
		 * /IMUser/IDGroupSections
		 * /Boot
		 * */
		try {
			Stat nodeStat = this.zk.exists("/IMServer", false);
			//如果条件成立，说明zookeeper上面没有最基本的目录节点，那么就创建最基本的节点
			if(nodeStat == null) {
				// /IMServer
				this.zk.create("/IMServer", "IMServer".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
				// /IMUser
				this.zk.create("/IMUser", "IMUser".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
				// /IMUser/ipxs
				this.zk.create("/IMUser/ipxs", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
				// /IMUser/IDSections
				this.zk.create("/IMUser/IDSections", "maxID".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
				// /IMUser/IDGroupSections
				this.zk.create("/IMUser/IDGroupSections", "maxID".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
				// /Boot
				this.zk.create("/Boot", "Boot".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		/*
		 * 开始进行监听器的初次加载
		 * */
		try {
			this.zk.exists("/IMUser/ipxs", this.imUserWatcher);
			this.zk.getChildren("/IMUser/ipxs", this.imUserWatcher);
			
			List<String> serverList = this.zk.getChildren("/IMServer", this.imServerWatcher);
			for (String serverpath : serverList) {
				this.zk.exists("/IMServer/" + serverpath, this.imServerWatcher);
				this.zk.getChildren("/IMServer/" + serverpath, this.imServerWatcher);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public ZooKeeper getZk() {
		return zk;
	}

	public void setZk(ZooKeeper zk) {
		this.zk = zk;
	}
}
